package com.alibaba.algo.apiimpl.dict;

import com.alibaba.algo.cooperation.common.BaseResult;
import com.alibaba.algo.cooperation.usercomponent.service.dict.SysDictService;
import com.alibaba.algo.cooperation.usercomponent.vo.req.dict.CreateDictRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.req.dict.DeleteDictRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.req.dict.SelectDictListRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.req.dict.UpdateDictRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.dict.SysDictResponseVO;
import com.alibaba.algo.core.base.PagerEntity;
import com.alibaba.algo.core.base.YesOrNo;
import com.alibaba.algo.core.exception.BaseException;
import com.alibaba.algo.domain.dict.SysDictDomain;
import com.alibaba.algo.entity.dict.SysDict;
import com.alibaba.algo.exception.BaseErrorCode;
import com.alibaba.algo.exception.SysDictErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * 数据字典
 */
@Slf4j
@RestController
public class SysDictServiceImpl implements SysDictService {

    @Resource
    private SysDictDomain sysDictDomain;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public BaseResult insert(CreateDictRequestVO param) {
        baseCheck(param.getCode(), param.getName(), param.getDesc());
        SysDict temp = new SysDict();
        temp.setCode(param.getCode());
        if (sysDictDomain.countByPara(temp) > 0) {
            throw new BaseException(SysDictErrorCode.CODE_REPEAT.getCode(), SysDictErrorCode.CODE_REPEAT.getMessage());
        }
        temp.setName(param.getName());
        temp.setDesc(param.getDesc());
        temp.setSort(param.getSort());
        temp.setParentCode(param.getParentCode());
        sysDictDomain.insert(temp);
        return BaseResult.buildSuccess();
    }

    private void baseCheck(String code, String name, String desc) {
        if (code == null || code.isEmpty()) {
            throw new BaseException(BaseErrorCode.CODE_IS_NULL.getCode(), BaseErrorCode.CODE_IS_NULL.getMessage());
        }
        if (code.length() > 100) {
            throw new BaseException(SysDictErrorCode.CODE_IS_TOO_LONG.getCode(), SysDictErrorCode.CODE_IS_TOO_LONG.getMessage());
        }
        if (name == null || name.isEmpty()) {
            throw new BaseException(BaseErrorCode.NAME_IS_NULL.getCode(), BaseErrorCode.NAME_IS_NULL.getMessage());
        }
        if (name.length() > 100) {
            throw new BaseException(SysDictErrorCode.NAME_IS_TOO_LONG.getCode(), SysDictErrorCode.NAME_IS_TOO_LONG.getMessage());
        }
        if (desc != null && desc.length() > 200) {
            throw new BaseException(SysDictErrorCode.DESC_IS_TOO_LONG.getCode(), SysDictErrorCode.DESC_IS_TOO_LONG.getMessage());
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public BaseResult delete(DeleteDictRequestVO param) {
        if (param.getIds() != null) {
            for (Long id : param.getIds()) {
                SysDict temp = new SysDict();
                temp.setId(id);
                temp.setIsDeleted(YesOrNo.Y.name());
                sysDictDomain.updateById(temp);
            }
        }
        return BaseResult.buildSuccess();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public BaseResult update(UpdateDictRequestVO param) {
        baseCheck(param.getCode(), param.getName(), param.getDesc());

        SysDict temp = new SysDict();
        temp.setCode(param.getCode());
        List<SysDict> list = sysDictDomain.listByPara(temp, null);
        if (list != null) {
            for (SysDict dict : list) {
                if (!dict.getId().equals(param.getId())) {
                    throw new BaseException(SysDictErrorCode.CODE_REPEAT.getCode(), SysDictErrorCode.CODE_REPEAT.getMessage());
                }
            }
        }
        SysDict sysDict = new SysDict();
        sysDict.setId(param.getId());
        sysDict.setCode(param.getCode());
        sysDict.setSort(param.getSort());
        sysDict.setName(param.getName());
        sysDict.setDesc(param.getDesc());
        sysDict.setParentCode(param.getParentCode());

        sysDictDomain.updateById(sysDict);
        return BaseResult.buildSuccess();
    }

    @Override
    public BaseResult<PagerEntity> selectPage(SelectDictListRequestVO param) {
        LinkedHashMap<String, Object> sortMap = new LinkedHashMap<>();
        sortMap.put("sort", "ASC");

        SysDict sysDict = new SysDict();
        sysDict.setNameKey(param.getNameKey());
        sysDict.setRootDict(param.isRootDict());
        sysDict.setCodeKey(param.getCodeKey());
        sysDict.setParentCode(param.getParentCode());

        return BaseResult.buildSuccess(sysDictDomain.selectPage(sysDict, param.getPageIndex(), param.getPageSize(), sortMap));
    }

    @Override
    public BaseResult<List<SysDictResponseVO>> selectList(SelectDictListRequestVO param) {
        LinkedHashMap<String, Object> sortMap = new LinkedHashMap<>();
        sortMap.put("sort", "ASC");
        SysDict sysDict = new SysDict();
        sysDict.setParentCode(param.getParentCode());
        String codeKey = param.getCodeKey();
        if (codeKey != null && !codeKey.isEmpty()) {
            sysDict.setCodeKey("%" + codeKey + "%");
        }
        String nameKey = param.getNameKey();
        if (nameKey != null && !nameKey.isEmpty()) {
            sysDict.setNameKey("%" + nameKey + "%");
        }
        sysDict.setRootDict(param.isRootDict());
        List<SysDict> sysDictList = sysDictDomain.listByPara(sysDict, sortMap);

        List<SysDictResponseVO> resourceResponseVOList = new ArrayList<>();
        sysDictList.forEach(sysRes -> {
            SysDictResponseVO sysDictResponseVO = new SysDictResponseVO();
            BeanUtils.copyProperties(sysRes, sysDictResponseVO);
            resourceResponseVOList.add(sysDictResponseVO);
        });
        return BaseResult.buildSuccess(resourceResponseVOList);
    }
}
